package com.sharding.sphere.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author xiangminwen
 * @since 2021/9/8 10:12
 */
@Slf4j
public class YhpHttpClientUtil {
    private static final CloseableHttpClient HTTP_CLIENT;
    // 池中获取链接超时时间 - ms毫秒
    private static final int REQUEST_TIME_OUT = 5000;
    // 建立链接超时时间 - ms毫秒
    private static final int CONNECT_TIME_OUT = 5000;
    // 读取超时时间 - ms毫秒
    private static final int SOCKET_TIME_OUT = 15000;
    // 最大连接数
    private static final int MAX_TOTAL = 500;
    // 每个路由的最大连接数
    private static final int MAX_PER_ROUTE = 100;
    //设置编码
    private static final String CHARSET = "utf-8";

    static {
        ConnectionSocketFactory plain = PlainConnectionSocketFactory.getSocketFactory();
        LayeredConnectionSocketFactory ssl = SSLConnectionSocketFactory.getSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", plain)
                .register("https", ssl)
                .build();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        // 将最大连接数增加
        cm.setMaxTotal(MAX_TOTAL);
        // 将目标主机的最大连接数增加
        cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);
        // 配置请求的超时设置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(REQUEST_TIME_OUT)
                .setConnectTimeout(CONNECT_TIME_OUT)
                .setSocketTimeout(SOCKET_TIME_OUT)
                .build();
        HTTP_CLIENT = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build();
    }

    public static String doGet(String url, Map<String, String> param) {
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (param != null && !param.isEmpty()) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            HttpGet httpGet = new HttpGet(uri);
            response = HTTP_CLIENT.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity(), CHARSET);
            }
        } catch (Exception e) {
            log.error("YhpHttpClient doGet error", e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException ignored) {
                }
            }
        }
        return null;
    }

    public static String doPost(String url, Map<String, String> param) {
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            if (param != null && !param.isEmpty()) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, CHARSET);
                httpPost.setEntity(entity);
            }
            response = HTTP_CLIENT.execute(httpPost);
            return EntityUtils.toString(response.getEntity(), CHARSET);
        } catch (Exception e) {
            log.error("YhpHttpClient doPost error", e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException ignored) {
                }
            }
        }
        return null;
    }

    public static String doPostJson(String url, String json) {
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            response = HTTP_CLIENT.execute(httpPost);
            return EntityUtils.toString(response.getEntity(), CHARSET);
        } catch (Exception e) {
            log.error("YhpHttpClient doPostJson error", e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException ignored) {
                }
            }
        }
        return null;
    }
}
